package com.sevntu.apvs.dModel.tests;

import junit.framework.Assert;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.junit.BeforeClass;
import org.junit.Test;

import com.sevntu.apvs.dModel.CircuitLoader;
import com.sevntu.apvs.dModel.DModel;
import com.sevntu.apvs.dModel.DModelException;

/**
 * Test class for checking the loading of XML config file.
 * 
 * @author <a href="mailto:rd.ryly@gmail.com">Ruslan Diachenko</a>
 */
public class CircuitLoaderTest {

	/** Use for log message generation */
	private static final Logger LOG = Logger.getLogger(CircuitLoaderTest.class.getName());

	private CircuitLoader loader;

	private DModel dModel;

	@BeforeClass
	public static void initLog4jProperties() {
		PropertyConfigurator.configure("config/log4j.properties");
	}

	@Test
	public void test1GetDModel() throws DModelException {
		loader = new CircuitLoader();
		dModel = loader.getDModel("src/com/sevntu/apvs/dModel/testinputs/circuit.xml");

		Assert.assertEquals("4OR-NOT", dModel.getElemList().get(0).name);
		Assert.assertEquals(1, dModel.getElemList().get(0).id);

		Assert.assertEquals(1, dModel.getCircuitList().get(0).getCircuitId());
		Assert.assertEquals(0, dModel.getCircuitList().get(0).getElemNumOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemContactOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemNumIn());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemContactIn());

		Assert.assertEquals(1, loader.getSchemeEntryNum());
		LOG.info("Test was successfuly complited.");
	}

	@Test
	public void test2GetDModel() throws DModelException {
		loader = new CircuitLoader();
		dModel = loader.getDModel("src/com/sevntu/apvs/dModel/testinputs/circuit2.xml");

		Assert.assertEquals("2OR-NOT", dModel.getElemList().get(0).name);
		Assert.assertEquals(1, dModel.getElemList().get(0).id);

		Assert.assertEquals("2OR-NOT", dModel.getElemList().get(1).name);
		Assert.assertEquals(2, dModel.getElemList().get(1).id);

		Assert.assertEquals("2OR-NOT", dModel.getElemList().get(2).name);
		Assert.assertEquals(3, dModel.getElemList().get(2).id);

		int index = 0;
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getCircuitId());
		Assert.assertEquals(0, dModel.getCircuitList().get(index).getElemNumOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getElemContactOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getElemNumIn());
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getElemContactIn());

		index++;
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getCircuitId());
		Assert.assertEquals(0, dModel.getCircuitList().get(index).getElemNumOut());
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getElemContactOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getElemNumIn());
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getElemContactIn());

		index++;
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getCircuitId());
		Assert.assertEquals(0, dModel.getCircuitList().get(index).getElemNumOut());
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getElemContactOut());
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getElemNumIn());
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getElemContactIn());

		index++;
		Assert.assertEquals(4, dModel.getCircuitList().get(index).getCircuitId());
		Assert.assertEquals(0, dModel.getCircuitList().get(index).getElemNumOut());
		Assert.assertEquals(4, dModel.getCircuitList().get(index).getElemContactOut());
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getElemNumIn());
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getElemContactIn());

		index++;
		Assert.assertEquals(5, dModel.getCircuitList().get(index).getCircuitId());
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getElemNumOut());
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getElemContactOut());
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getElemNumIn());
		Assert.assertEquals(1, dModel.getCircuitList().get(index).getElemContactIn());

		index++;
		Assert.assertEquals(6, dModel.getCircuitList().get(index).getCircuitId());
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getElemNumOut());
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getElemContactOut());
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getElemNumIn());
		Assert.assertEquals(2, dModel.getCircuitList().get(index).getElemContactIn());

		index++;
		Assert.assertEquals(7, dModel.getCircuitList().get(index).getCircuitId());
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getElemNumOut());
		Assert.assertEquals(3, dModel.getCircuitList().get(index).getElemContactOut());
		Assert.assertEquals(0, dModel.getCircuitList().get(index).getElemNumIn());
		Assert.assertEquals(5, dModel.getCircuitList().get(index).getElemContactIn());

		Assert.assertEquals(4, loader.getSchemeEntryNum());
		LOG.info("Test was successfuly complited.");
	}

	@Test
	public void test3GetDModel() throws DModelException {
		loader = new CircuitLoader();

		// First execution using the same object
		dModel = loader.getDModel("src/com/sevntu/apvs/dModel/testinputs/circuit.xml");

		Assert.assertEquals("4OR-NOT", dModel.getElemList().get(0).name);
		Assert.assertEquals(1, dModel.getElemList().get(0).id);

		Assert.assertEquals(1, dModel.getCircuitList().get(0).getCircuitId());
		Assert.assertEquals(0, dModel.getCircuitList().get(0).getElemNumOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemContactOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemNumIn());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemContactIn());

		Assert.assertEquals(1, loader.getSchemeEntryNum());

		// Second execution using the same object
		dModel = loader.getDModel("src/com/sevntu/apvs/dModel/testinputs/circuit.xml");

		Assert.assertEquals("4OR-NOT", dModel.getElemList().get(0).name);
		Assert.assertEquals(1, dModel.getElemList().get(0).id);

		Assert.assertEquals(1, dModel.getCircuitList().get(0).getCircuitId());
		Assert.assertEquals(0, dModel.getCircuitList().get(0).getElemNumOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemContactOut());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemNumIn());
		Assert.assertEquals(1, dModel.getCircuitList().get(0).getElemContactIn());

		Assert.assertEquals(1, loader.getSchemeEntryNum());
		LOG.info("Test was successfuly complited.");
	}

	@Test(expected = DModelException.class)
	public void test4GetDModel() throws DModelException {
		loader = new CircuitLoader();
		dModel = loader.getDModel("src/com/sevntu/apvs/dModel/testinputs/wrong_tag_value.xml");
	}
}
